var tetralat = {};
tetralat.panel = {};
tetralat.paraskinio = {};

tetralat.rank = 6;
tetralat.ipodixi = false;
tetralat.diamperes = false;

tetralat.paleta = [
	{ b: '91D6BC', c: '894E42', l: 'A' },
	{ b: 'FFBF01', c: '41634D', l: 'B' },
	{ b: '999966', c: '38244C', l: 'C' },
	{ b: 'AAFE19', c: '8A00B1', l: 'D' },
	{ b: 'FFFF00', c: '5700B2', l: 'E' },
	{ b: 'FF9966', c: '24B2A8', l: 'F' },
	{ b: '996633', c: '0A3D4C', l: 'G' },
	{ b: 'C14CFD', c: 'D7FD4C', l: 'H' },
	{ b: 'CC9900', c: '00177F', l: 'I' },
	{ b: 'F35050', c: '00B275', l: 'J' },
	{ b: '47AE28', c: '610352', l: 'K' },
	{ b: 'C4C8B9', c: '71597B', l: 'L' },
	{ b: '335C85', c: '38270A', l: 'M' },
	{ b: '4F9966', c: '99504F', l: 'N' },
	{ b: '666699', c: '4C4524', l: 'O' },
	{ b: 'FFFF99', c: '333333', l: 'P' },
	{ b: 'FF3333', c: 'FFFF33', l: 'Q' },
	{ b: 'FFCCCC', c: '003399', l: 'R' },
	{ b: '1F2E00', c: 'FFFF99', l: 'S' },
	{ b: 'E0FFA3', c: 'FF3300', l: 'T' },
	{ b: '993333', c: 'FFFF99', l: 'U' },
	{ b: 'FFAD5C', c: 'FF0066', l: 'V' },
	{ b: '5C5C3D', c: '99FF66', l: 'W' },
	{ b: 'FFCC00', c: 'FF3399', l: 'X' },
	{ b: '85A366', c: '006699', l: 'Y' },
	{ b: '660066', c: 'CCFF99', l: 'Z' }
];

tetralat.proetimasia = function() {
	tetralat.kontino = null;

	var main = getelid('main');
	if (notSet(main)) { return; }
	svisePeriexomeno(main);

	var debug = document.createElement('div');
	if (notSet(debug)) { return null; }
	debug.setAttribute('id', 'debug');
	debug.setAttribute('class', 'debug');

	var tablo = document.createElement('div');
	if (notSet(tablo)) { return null; }
	tablo.setAttribute('id', 'tablo');
	tablo.setAttribute('class', 'tablo');

	var panel = document.createElement('div');
	if (notSet(panel)) { return null; }
	panel.setAttribute('id', 'panel');
	panel.setAttribute('class', 'panel');

	var paleta = document.createElement('div');
	if (notSet(paleta)) { return null; }
	paleta.setAttribute('id', 'paleta');
	paleta.setAttribute('class', 'paleta');

	var istoriko = document.createElement('div');
	if (notSet(istoriko)) { return null; }
	istoriko.setAttribute('id', 'istoriko');
	istoriko.setAttribute('class', 'istoriko');

	main.appendChild(debug);
	main.appendChild(tablo);
	main.appendChild(panel);
	main.appendChild(paleta);
	main.appendChild(istoriko);

	// Υπολογίζουμε διάφορα μεγέθη που θα μας χρειαστούν
	// τόσο στην χωροθέτηση των βασικών περιοχών της
	// σελίδας, όσο και στο ίδιο το παιχνίδι.
	// Πρώτο στοιχείο που υπολογίζουμε είναι το πλάτος
	// της ωφέλιμης περιοχής. Αυτό προκύπτει αρχικά
	// από την αφαίρεση του πλάτους του κεντρικού
	// cotrol panel από το συνολικό πλάτος της σελίδας.
	var wall = main.clientWidth -  panel.clientWidth;

	// Υπολογίζουμε τώρα το πλάτος των δύο βασικών
	// περιοχών του παιχνιδιού που είναι το ταμπλό
	// και η παλέτα. Διαιρούμε με νούμερο μεγαλύτερο
	// από το 2, ώστε να αφήσουμε και χώρο μεταξύ
	// των τριών περιοχών του παιχνιδιού.
	var w = parseInt(wall / 2.1);

	// Το στοιχείο "di" είναι η διάσταση κάθε οικοπέδου.
	// Οικόπεδα ονομάζονται οι ευρύτερες περιοχές κάθε
	// στοιχείου (αριθμού). Τα οικόπεδα εφάπτονται μεταξύ
	// τους χωρίς να υπάρχει κενό ή σύνορο κάποιου πλάτους.
	tetralat.di = Math.round(w / tetralat.rank);

	// Σε κάθε οικόπεδο περιέχονται μικρότερες περιοχές
	// που ονομάζονται τετράγωνα. Αυτά είναι τα κινούμενα
	// φορεία που περιέχουν τους αριθμούς και είναι
	// χρωματισμένα με τα χρώματα του παιχνιδιού.
	// Το στοιχείο "dt" είναι η διάσταση κάθε τετραγώνου
	// και είναι ελαφρώς μικρότερη από τη διάσταση υων
	// οικοπέδων ("di").
	tetralat.dt = Math.round(tetralat.di * 0.9);

	// Το στοιχείο "xx" είναι η διάσταση το μικρού κόκκινου
	// τετραγώνου που σημαίνει τον αποκλεισμό του τετραγώνου.
	tetralat.dxx = parseInt(tetralat.dt / 2.2);

	// Το πεδίο "dit" είναι το πλάτος του πεζοδρομίου, δηλαδή
	// του περιθωρίου που περισσεύει μεταξύ οικοπέδου και
	// τετραγώνου.
	tetralat.dit = Math.round((tetralat.di - tetralat.dt) / 2);

	// Μέσα σε κάθε τετράγωνο περιέχεται πλακίδιο που φέρει
	// τον αριθμό και το χρώμα του τετραγώνου. Το πλακίδιο
	// έχει ελαφρώς μικρότερη διάσταση από το τετράγωνο
	// δημιουργώντας έτσι την ψευδαίσθηση πλαισίου που
	// περιβάλλει κάθε πλακίδιο. Η διάσταση των πλακιδίων
	// είναι το πεδίο "dp".
	tetralat.dp = Math.round(tetralat.dt * 0.9);

	// Το πεδίο "dtp" δείχνει το πλάτος του περιθωρίου που
	// σχηματίζεται μεταξύ τετραγώνου και πλακιδίου.
	tetralat.dtp = Math.round((tetralat.dt - tetralat.dp) / 2);

	// Το πεδίο "fs" είναι ήσσονος σημασίας και δείχνει το
	// μέγεθος της γραμματοσειράς που χρησιμοποιείται για
	// την αναγραφή των αριθμών. Το μέγεθος αυτό δίνεται
	// συναρτήσει της διάστασης του πλακιδίου.
	tetralat.fs = Math.round(tetralat.dp * 0.8);

	// Αναπροσαρμόζουμε τώρα το πλάτος των βασικών περιοχών
	// με βάση την τάξη και τη διάσταση κάθε οικοπέδου.
	w = tetralat.rank * tetralat.di;

	// Υπολογίζω το δεξί και αριστερό περιθώριο διαιρώντας
	// το περίσσευμα δια του 3. Πράγματι, ένα περιθώριο θα
	// έχουμε αριστερά του ταμπλό (αριστερά), ένα περιθώριο
	// θα έχουμε δεξιά της παλέτας (δεξιά) και το τρίτο θα
	// μοιραστεί εκατέρωθεν του control panel (κεντρική στήλη).
	var d = Math.round((wall - (2 * w)) / 3.0);
	var dmiso = Math.round((wall - (2 * w)) / 6.0);

	// Ακολουθεί τοποθέτηση και σχηματισμός της περιοχής του ταμπλό.
	tablo.style.top = d + 'px';
	tablo.style.left = d + 'px';
	tablo.style.width = w + 'px';
	tablo.style.height = w + 'px';

	// Ακολουθεί τοποθέτηση και σχηματισμός της περιοχής του control panel.
	panel.style.top = d + 'px';
	panel.style.left = (d + w + dmiso) + 'px';
	panel.style.height = (tetralat.rank * tetralat.di) + 'px';

	// Ακολουθεί τοποθέτηση και σχηματισμός της περιοχής της παλέτας.
	paleta.style.top = d + 'px';
	paleta.style.left = (d + w + dmiso + panel.clientWidth + dmiso) + 'px';
	paleta.style.width = w + 'px';
	paleta.style.height = w + 'px';

	tetralat.ftiaxeTablo(main, tablo);
	tetralat.ftiaxePanel(panel);
	tetralat.ftiaxePaleta(main, paleta);
	tetralat.ftiaxeIstoriko(main, tablo, paleta, istoriko);

	if (tetralat.ipodixi) {
		tetralat.ipodixi = !tetralat.ipodixi;
		tetralat.panel.ipodixi();
	}

	if (tetralat.diamperes) {
		tetralat.diamperes = !tetralat.diamperes;
		tetralat.panel.diamperes();
	}
};

// Το ταμπλό έχει παρόμοια δομή με την παλέτα. Περιέχει
// οικόπεδα και τετράγωνα που τοπθετούνται εντός των
// οικοπέδων. Εδώ το οικόπεδο ονομάζεται "odekopi"
// και το τετράγωνο "onogartet", χρησιμοποιούμε δηλαδή
// δηλαδή τα ανάστροφα των ονομάτων "ikopedo" και
// "tetragono".

tetralat.ftiaxeTablo = function(main, tablo) {
	tetralat.tt = parseInt(tablo.style.top);
	tetralat.tl = parseInt(tablo.style.left);

	for (var i = 0; i < tetralat.rank; i++) {
		for (var j = 0; j < tetralat.rank; j++) {
			var p = tetralat.odepoki(i, j);
			if (notSet(p)) { return; }
			main.appendChild(p);

			p = tetralat.onogartet(i, j);
			if (notSet(p)) { return; }
			main.appendChild(p);
		}
	}
};

tetralat.odepoki = function(grami, stili) {
	var p = document.createElement('div');
	if (notSet(p)) { return null; }

	p.setAttribute('id', 'o:' + grami + ':' + stili);
	p.setAttribute('class', 'ikopedo');

	p.style.width = tetralat.di + 'px';
	p.style.height = tetralat.di + 'px';

	p.style.top = (tetralat.tt + (grami * tetralat.di)) + 'px';
	p.style.left = (tetralat.tl + (stili * tetralat.di)) + 'px';
	p.tetralat = tetralat.data(p);
	return p;
};

tetralat.onogartet = function(grami, stili) {
	var p = document.createElement('div');
	if (notSet(p)) { return null; }

	p.setAttribute('class', 'tetragono kato');

	p.style.width = tetralat.dt + 'px';
	p.style.height = tetralat.dt + 'px';

	p.style.top = (tetralat.tt + (grami * tetralat.di) + tetralat.dit) + 'px';
	p.style.left = (tetralat.tl + (stili * tetralat.di) + tetralat.dit) + 'px';

	var q = document.createElement('div');
	if (notSet(q)) { return null; }

	q.setAttribute('id', 'd:' + grami + ':' + stili);
	q.setAttribute('class', 'dekto');

	q.style.width = tetralat.dp + 'px';
	q.style.height = tetralat.dp + 'px';

	q.style.top = tetralat.dtp + 'px';
	q.style.left = tetralat.dtp + 'px';

	p.appendChild(q);
	return p;
};

tetralat.istorikoSave = function(istoriko) {
	if (notSet(istoriko)) {
		istoriko = getelid('istoriko');
		if (notSet(istoriko)) { return false; }
	}

	if (isSet(tetralat.istorikoHTML)) { return false; }
	tetralat.istorikoHTML = istoriko.innerHTML;
	return true;
};

tetralat.istorikoRestore = function(istoriko) {
	if (notSet(istoriko)) {
		istoriko = getelid('istoriko');
		if (notSet(istoriko)) { return false; }
	}

	if (notSet(tetralat.istorikoHTML)) { return false; }
	istoriko.innerHTML = tetralat.istorikoHTML;
	tetralat.istorikoHTML = null;
	return true;
};

tetralat.ftiaxePanel = function(panel) {
	var blist = [
		{ img: 'ligotera.png',		act: 'ligotera',	tit: 'Reduce the rank' },
		{ img: 'neo.png',		act: 'neo',		tit: 'Begin new' },
		{ img: 'perisotera.png',	act: 'perisotera',	tit: 'Increase the rank' },
		{ img: (tetralat.ipodixi ? 'kripseIpodixi.png' : 'dixeIpodixi.png'),
			act: 'ipodixi', tit: (tetralat.ipodixi ? 'Hide hints' : 'Show hints') },
		{ img: (tetralat.diamperes ? 'diamperesOff.png' : 'diamperesOn.png'),
			act: 'diamperes', tit: (tetralat.diamperes ? 'Show canvas' : 'Hide canvas') },
		{ img:	'bugFix.png',		act: 'bugFix', tit: 'Fix bugs' },
		{ img: 'paraskinio.png',	act: 'paraskinioSwitch',
			tit: 'Switch background' },
		{ img: 	null}
	];

	for (var i = 0; i < blist.length; i++) {
		if (notSet(blist[i].img)) { break; }

		var b = tetralat.panelButton(blist[i]);
		if (isSet(b)) { panel.appendChild(b); }
	}
};

tetralat.panelButton = function(x) {
	// Ετοιμάζουμε πρώτα το εικονίδιο.
	var p = document.createElement('img');
	if (notSet(p)) { return null; }

	p.setAttribute('class', 'panelIcon');
	p.src = globals.server + 'images/panel/' + x['img'];

	// Τώρα ετοιμάζουμε το κουμπί.
	var b = document.createElement('div');
	if (notSet(b)) { return null; }

	b.appendChild(p);
	b.setAttribute('class', 'panelButton');
	b.title = x['tit'];
	b.onmouseover = function() {
		b.setAttribute('class', 'panelButton panelButtonEpilogi');
	};
	b.onmouseout = function() {
		b.setAttribute('class', 'panelButton');
	};
	b.onclick = function() {
		if (isSet(p)) {
			p.prevSrc = p.getAttribute('src');
			p.setAttribute('src', globals.server + 'images/movingSquares.gif');
		}
		setTimeout(function() {
			tetralat.panel[x['act']](p);
			p.setAttribute('src', p.prevSrc);
		}, 100);
	};
	return b;
};

tetralat.ftiaxePaleta = function(main, paleta) {
	tetralat.pt = parseInt(paleta.style.top);
	tetralat.pl = parseInt(paleta.style.left);

	// Στα οικόπεδα της παλέτας υπάρχουν δύο τετράγωνα
	// σε κάθε θέση τοποθετημένα το ένα επάνω στο άλλο.
	// Το κάτω τετράγωνο είναι αυτό που θα αχνοφαίνεται
	// όταν μετακινηθεί το αντίστοιχο τετράγωνο.
	// Στο κάτω τετράγωνο υπάρχει εικόνα με κόκκινο "X"
	// που εμφανίζεται με την απόθεση του κανονικού
	// τετραγώνου στο ταμπλό.

	for (var i = 0; i < tetralat.rank; i++) {
		for (var j = 0; j < tetralat.rank; j++) {
			var p = tetralat.ikopedo(i, j);
			if (notSet(p)) { return; }
			main.appendChild(p);

			p = tetralat.tetragono(i, j, 'kato');
			if (notSet(p)) { return; }
			main.appendChild(p);

			var q = tetralat.taken(i, j);
			if (notSet(q)) { return; }
			p.appendChild(q);

			p = tetralat.tetragono(i, j, 'pano');
			if (notSet(p)) { return; }
			main.appendChild(p);
		}
	}
	
};

tetralat.ftiaxeIstoriko = function(main, tablo, paleta, istoriko) {
	istoriko.style.width = (paleta.offsetLeft + paleta.clientWidth - tablo.offsetLeft) + 'px';
	var h1 = main.clientHeight - tablo.offsetTop - tablo.clientHeight;
	var h2 = parseInt(h1 * 0.9);
	istoriko.style.height = h2 + 'px';
	istoriko.style.top = (tablo.offsetTop + tablo.clientHeight + h1 - h2) + 'px';
	istoriko.style.left = tablo.style.left;
	tetralat.istorikoHTML = null;

	var tw = parseInt(h2 / 2.1);
	var nt = parseInt(istoriko.clientWidth / tw);
	tetralat.paraskinio.thumbWidth = (tw - 4) + 'px';

};

tetralat.ikopedo = function(grami, stili) {
	var x = document.createElement('div');
	if (notSet(x)) { return null; }

	x.setAttribute('id', 'xx:' + grami + ':' + stili);
	x.setAttribute('class', 'adinato');

	x.style.width = tetralat.dxx + 'px';
	x.style.height = tetralat.dxx + 'px';

	x.style.top = tetralat.dit + 'px';
	x.style.left = tetralat.dit + 'px';

	var p = document.createElement('div');
	if (notSet(p)) { return null; }

	p.setAttribute('id', 'i:' + grami + ':' + stili);
	p.setAttribute('class', 'ikopedo');

	p.style.width = tetralat.di + 'px';
	p.style.height = tetralat.di + 'px';

	p.style.top = (tetralat.pt + (grami * tetralat.di)) + 'px';
	p.style.left = (tetralat.pl + (stili * tetralat.di)) + 'px';
	p.tetralat = tetralat.data(p);

	p.appendChild(x);
	return p;
};

tetralat.tetragono = function(grami, stili, katoPano) {
	var p = document.createElement('div');
	if (notSet(p)) { return null; }

	p.setAttribute('id', (katoPano == 'pano' ? 't' : 'b') + ':' + grami + ':' + stili);
	p.setAttribute('class', 'tetragono ' + katoPano);

	p.style.width = tetralat.dt + 'px';
	p.style.height = tetralat.dt + 'px';

	p.style.top = (tetralat.pt + (grami * tetralat.di) + tetralat.dit) + 'px';
	p.style.left = (tetralat.pl + (stili * tetralat.di) + tetralat.dit) + 'px';
	if (katoPano == 'pano') {
		p.onmouseover = function() { tetralat.dixePrama(grami, stili); };
		p.onmouseout = function() { tetralat.kripsePrama(); };
		p.onmousedown = function(event) { tetralat.moveIt(event, grami, stili); };
		p.onmouseup = function(event) { tetralat.leaveIt(event, grami, stili); };
	}

	var q = tetralat.plakidio(grami, stili, katoPano);
	if (notSet(q)) { return p; }

	p.appendChild(q);
	return p;
};

tetralat.taken = function(grami, stili) {
	var p = document.createElement('img');
	if (notSet(p)) { return; }

	p.setAttribute('id', 'x:' + grami + ':' + stili);
	p.setAttribute('class', 'taken paraKato');

	p.style.width = tetralat.dt + 'px';
	p.style.height = tetralat.dt + 'px';

	p.src = globals.server + 'images/taken.png';
	return p;
};

tetralat.plakidio = function(grami, stili, katoPano) {
	var t = document.createTextNode(tetralat.paleta[stili].l);
	if (notSet(t)) { return null; }

	var l = document.createElement('div');
	if (notSet(l)) { return null; }

	l.setAttribute('class', 'latin');
	l.appendChild(t);

	var p = document.createElement('div');
	if (notSet(p)) { return null; }

	if (katoPano == 'pano') { p.setAttribute('id', 'p:' + grami + ':' + stili); }
	p.setAttribute('class', 'plakidio ' + katoPano);

	p.style.width = tetralat.dp + 'px';
	p.style.height = tetralat.dp + 'px';

	p.style.top = tetralat.dtp + 'px';
	p.style.left =  tetralat.dtp + 'px';

	p.style.backgroundColor = '#' + tetralat.paleta[grami].b;
	if (!tetralat.xromaGrama) { p.style.color = '#' + tetralat.paleta[grami].c; }
	p.style.fontSize = tetralat.fs + 'px';

	p.appendChild(l);
	return p;
};

// Επιστρέφει αντικείμενο με διάφορα δεδομένα που αφορούν στη
// συγκεκριμένη θέση. Κάποια από αυτά είναι οι αρχικές συντεταγμένες
// της θέσης, η αρχική προδιαγραφή CSS, η θέση του ταμπλό που έχει καταλάβει
// το συγκεκριμένο τετράγωνο και το αν είναι κατειλημμένο ή όχι.

tetralat.data = function(p) {
	return {
		'top':		parseInt(p.style.top),
		'left':		parseInt(p.style.left),
		'class':	p.getAttribute('class'),
		'sxetiko':	null
	};
};

tetralat.dixePrama = function(grami, stili) {
	if (tetralat.ipodixi) {
		tetralat.dixeDekta(grami, stili);
	}
};

tetralat.kripsePrama = function() {
	if (tetralat.ipodixi) {
		tetralat.kripseDekta();
	}
};

tetralat.moveIt = function(e, grami, stili) {
	tetralat.debug.titlos('Μετακίνηση πλακιδίου (' + grami + ', ' + stili + ')');
	if (notSet(e)) { e = window.event; }
	// IE uses srcElement, others use target
	var target = e.target != null ? e.target : e.srcElement;

	if (tetralat.ipodixi) {
		tetralat.adinata.moving = null;
		tetralat.adinata.stoxos = null;
		tetralat.adinata.clearAdinato(grami, stili);
	}

	var x = getelid('p:' + grami + ':' + stili);
	if (notSet(x)) { return; }
	x.setAttribute('class', 'plakidio kinisi');

	// dotted border around "ikopedo"
	x = getelid('b:' + grami + ':' + stili);
	if (notSet(x)) { return; }
	x.setAttribute('class', 'ikopedo epilegmeno');

	x = getelid('x:' + grami + ':' + stili);
	if (notSet(x)) { return; }
	x.style.display = 'none';

	var x = getelid('t:' + grami + ':' + stili);
	if (notSet(x)) { return; }
	x.setAttribute('class', 'tetragono kinisi skia');

	var mx0 = e.clientX;
	var my0 = e.clientY;

	var top0 = parseInt(x.style.top);
	var left0 = parseInt(x.style.left);

	var arxiko = getelid('i:' + grami + ':' + stili);
	if (isSet(arxiko.tetralat.sxetiko)) {
		arxiko.tetralat.sxetiko.tetralat.sxetiko = null;
		arxiko.tetralat.sxetiko = null;
	}

	if (tetralat.ipodixi) {
		tetralat.dixeDekta(grami, stili);
	}

	document.onmousemove = function(e) {
		if (notSet(e)) { e = window.event; }
		dx = (e.clientX - mx0);
		dy = (e.clientY - my0);
		x.style.top = (top0 + dy) + 'px';
		x.style.left = (left0 + dx) + 'px';
		var p = tetralat.vresKontino(x);
		if (notSet(tetralat.kontino)) {
			tetralat.kontino = p;
		}
		else if (p != tetralat.kontino) {
			tetralat.emfanesKontino(false);
			tetralat.kontino = p;
		}
		tetralat.emfanesKontino(true);
		if (tetralat.ipodixi) {
			tetralat.adinata.dixe(x, p);
		}
	};

        // cancel out any text selections
        document.body.focus();

        // prevent text selection in IE
        document.onselectstart = function () { return false; };

	// prevent IE from trying to drag an image
        target.ondragstart = function() { return false; };

        
        // prevent text selection (except IE)
        return false;
};

tetralat.emfanesKontino = function(yes) {
	if (tetralat.kontino.getAttribute('id').match(/^i:/)) { return; }

	if (yes) {
		tetralat.kontino.setAttribute('class', tetralat.kontino.tetralat['class'] + ' kontino');
		tetralat.kontino.style.display = 'inline';
	}
	else {
		tetralat.kontino.setAttribute('class', tetralat.kontino.tetralat['class']);
		if (tetralat.kontino.getAttribute('id').match(/^o:/)) {
			tetralat.kontino.style.display = tetralat.diamperes ? 'none' : 'inline';
		}
	}
};

tetralat.leaveIt = function(e, grami, stili) {
	if (notSet(e)) { e = window.event; }
	var x = getelid('p:' + grami + ':' + stili);
	if (notSet(x)) { return; }
	x.setAttribute('class', 'plakidio pano');

	var t = getelid('t:' + grami + ':' + stili);
	if (notSet(t)) { return; }
	t.setAttribute('class', 'tetragono pano');

	x = getelid('b:' + grami + ':' + stili);
	if (notSet(x)) { return; }
	x.setAttribute('class', 'ikopedo');

	x = getelid('x:' + grami + ':' + stili);
	if (notSet(x)) { return; }
	x.style.display = 'inline';

	document.onmousemove = null;
	document.onselectstart = null;

	var arxiko = getelid('i:' + grami + ':' + stili);
	if (notSet(arxiko)) { return; }

	// Αν έχουμε κάνει απλώς κλικ στο πλακίδιο χωρίς να το κουνήσουμε
	// καθόλου, τότε το πλακίδιο επιστρέφει στην αρχική του θέση.
	if (notSet(tetralat.kontino)) { tetralat.kontino = arxiko; }

	tetralat.emfanesKontino(false);
	if (tetralat.kontino.id.match(/^i:/)) {
		var k = arxiko;
	}
	else {
		k = tetralat.kontino;
		arxiko.tetralat.sxetiko = k;
		k.tetralat.sxetiko = arxiko;
	}
	t.style.top = (k.tetralat.top + tetralat.dit) + 'px';
	t.style.left = (k.tetralat.left + tetralat.dit) + 'px';
	tetralat.kontino = null;

	if (tetralat.ipodixi) {
		tetralat.kripseDekta();
		tetralat.adinata.dixe(t, k);
	}

	tetralat.dixeLathos();
};

tetralat.dixeDekta = function(grami, stili) {
	var gnok = [];
	var snok = [];

	for (var i = 0; i < tetralat.rank; i++) {
		for (var j = 0; j < tetralat.rank; j++) {
			var p = getelid('o:' + i + ':' + j);
			if (notSet(p)) { continue; }
			if (notSet(p.tetralat.sxetiko)) { continue; }

			// Αν το σχετικό πλακίδιο είναι αυτό με τα συγκεκριμένα
			// στοιχεία που ελέγχω, το εξαιρώ, καθώς το ίδιο μπορεί
			// να τοποθετηθεί στην ίδια στήλη ή γραμμή ως να μην
			// τοποθετημένο.
			if (p.tetralat.sxetiko.id == ('i:' + grami + ':' + stili)) { continue; }

			var x = p.tetralat.sxetiko.id.split(':');
			if (x.length != 3) { continue; }

			if ((x[1] == grami) || (x[2] == stili)) {
				gnok[i] = true;
				snok[j] = true;
			}
		}
	}

	for (var i = 0; i < tetralat.rank; i++) {
		if (isSet(gnok[i])) { continue; }

		for (var j = 0; j < tetralat.rank; j++) {
			if (isSet(snok[j])) { continue; }

			var p = getelid('o:' + i + ':' + j);
			if (notSet(p)) { continue; }
			if (isSet(p.tetralat.sxetiko)) { continue; }

			p = getelid('d:' + i + ':' + j);
			if (notSet(p)) { continue; }
			p.style.visibility = 'visible';
		}
	}
};

tetralat.kripseDekta = function() {
	for (var i = 0; i < tetralat.rank; i++) {
		for (var j = 0; j < tetralat.rank; j++) {
			var p = getelid('d:' + i + ':' + j);
			if (isSet(p)) { p.style.visibility = 'hidden'; }
		}
	}
};

tetralat.dixeLathos = function() {
	for (var i = 0; i < tetralat.rank; i++) {
		for (var j = 0; j < tetralat.rank; j++) {
			var p = getelid('o:' + i + ':' + j);
			if (notSet(p)) { continue; }
			if (notSet(p.tetralat.colorOk)) { continue; }

			p.style.backgroundColor = p.tetralat.colorOk;
			p.style.display = tetralat.diamperes ? 'none' : 'inline';
			p.tetralat.colorOk = null;
		}
	}
			
	var nerr = 0;
	for (var i = 0; i < tetralat.rank; i++) {
		nerr += tetralat.gramiLathos(i);
	}

	for (i = 0; i < tetralat.rank; i++) {
		nerr += tetralat.stiliLathos(i);
	}
	tetralat.checkDone(nerr);
};

tetralat.checkDone = function(nerr) {
	var main = getelid('main');
	if (notSet(main)) { return; }

	var p = getelid('doneIcon');
	if (isSet(p)) { main.removeChild(p); }
	if (nerr > 0) { return; }

	for (var i = 0; i < tetralat.rank; i++) {
		for (var j = 0; j < tetralat.rank; j++) {
			var p = getelid('i:' + i + ':' + j);
			if (notSet(p)) { return; }
			if (notSet(p.tetralat.sxetiko)) { return; }
		}
	}

	var p = document.createElement('img');
	p.setAttribute('id', 'doneIcon');
	p.setAttribute('class', 'doneIcon');
	p.setAttribute('src', globals.server + 'images/done.png');

	main.appendChild(p);
};

tetralat.gramiLathos = function(grami) {
	var nerr = 0;
	for (var i = tetralat.rank - 1; i > 0; i--) {
		var pivot = getelid('o:' + grami + ':' + i);
		if (notSet(pivot)) { continue; }
		if (notSet(pivot.tetralat.sxetiko)) { continue; }

		for (var j = 0; j < i; j++) {
			var target = getelid('o:' + grami + ':' + j);
			if (notSet(target)) { continue; }
			if (notSet(target.tetralat.sxetiko)) { continue; }
			nerr += tetralat.zevgariLathos(pivot, target);
		}
	}
	return nerr;
};

tetralat.stiliLathos = function(stili) {
	var nerr = 0;
	for (var i = tetralat.rank - 1; i > 0; i--) {
		var pivot = getelid('o:' + i + ':' + stili);
		if (notSet(pivot)) { continue; }
		if (notSet(pivot.tetralat.sxetiko)) { continue; }

		for (var j = 0; j < i; j++) {
			var target = getelid('o:' + j + ':' + stili);
			if (notSet(target)) { continue; }
			if (notSet(target.tetralat.sxetiko)) { continue; }
			nerr += tetralat.zevgariLathos(pivot, target);
		}
	}
	return nerr;
};

tetralat.zevgariLathos = function(p, q) {
	var x = p.tetralat.sxetiko.id.split(':');
	if (x.length != 3) { return 0; }

	var y = q.tetralat.sxetiko.id.split(':');
	if (y.length != 3) { return 0; }

	if ((y[1] != x[1]) && (x[2] != y[2])) { return 0; }

	if (notSet(p.tetralat.colorOk)) { p.tetralat.colorOk = p.style.backgroundColor; }
	p.style.backgroundColor = globals.color.piasmeno;
	p.style.display = 'inline';

	if (notSet(q.tetralat.colorOk)) { q.tetralat.colorOk = q.style.backgroundColor; }
	q.style.backgroundColor = globals.color.piasmeno;
	q.style.display = 'inline';

	return 1;
};

tetralat.vresKontino = function(x) {
	var mind = null;
	var q = null;

	for (var i = 0; i < tetralat.rank; i++) {
		for (var j = 0; j < tetralat.rank; j++) {
			var p = getelid('o:' + i + ':' + j);
			if (notSet(p)) { continue; }
			if (isSet(p.tetralat.sxetiko)) { continue; }

			var d = tetralat.apostasi(x, p);
			if (notSet(mind) || (d < mind)) {
				q = p;
				mind = d;
			}
		}
	}

	for (var i = 0; i < tetralat.rank; i++) {
		for (var j = 0; j < tetralat.rank; j++) {
			var p = getelid('i:' + i + ':' + j);
			if (notSet(p)) { continue; }

			var d = tetralat.apostasi(x, p);
			if (notSet(mind) || (d < mind)) {
				q = p;
				mind = d;
			}
		}
	}

	return q;
};

tetralat.apostasi = function(p, q) {
	var dy = parseInt(p.style.top) - parseInt(q.style.top);
	var dx = parseInt(p.style.left) - parseInt(q.style.left);
	return Math.sqrt((dx * dx) + (dy * dy));
};

tetralat.isagogikoSimioma = function() {
	if (isInternetExplorer()) {
		fyi('<span class="italic">Please avoid Internet Explorer, use Google Chrome ' +
			'for better performance</span>', 'fyiTop', 20000);
	}

	var p = getelid('istoriko');
	if (notSet(p)) { return; }

	var q = document.createElement('div');
	if (notSet(q)) { return; }

	q.setAttribute('class', 'isagogi');

	q.innerHTML = 'An idea of George Baloglou, based on the Orthogonal ' +
		'Latin Squares mathematical <a target="_blank" href="http://www.ams.org/' +
		'samplings/feature-column/fcarc-latinii1">problem</a> by Leonhard Euler. ' +
		'You may move tiles from the palette (right) to the panel ' +
		'(left) so that no tiles of the same color or letter may lie ' +
		'on the same row or column.';

	p.appendChild(q);
	setTimeout(function() {
		q.style.opacity = 0;
	}, 20000);
};

// Ακολουθούν ψευδοfunctions του debugger. Οι κανονικές
// functions του debugger βρίσκονται σε άλλο javascript
// αρχείο το οποίο φορτώνεται όταν έχει δοθεί παράμετρος
// "debug" στο URL.

tetralat.debug = {};
tetralat.debug.minima = function(msg, esoxi) {};
tetralat.debug.titlos = function(msg, klasi) {};
tetralat.debug.ipotitlos = function(msg) {};
tetralat.debug.init = function() {};


window.onload = function() {
	init();
	tetralat.proetimasia();
	tetralat.isagogikoSimioma();
	tetralat.debug.init();
};
